const plugin = require('windicss/plugin');

const dashToCamel = (str) => {
  if (!/-/.test(str)) return str;
  return str.toLowerCase().replace(/-(.)/g, (_, group) => group.toUpperCase());
};

const hslColors = plugin(
  ({ addDynamic, theme, config }) => {
    const cssAttrs = [
      'text',
      'bg',
      'border',
      'border-t',
      'border-r',
      'border-b',
      'border-l',
      'divide',
      'caret',
      'outline',
      'outline-solid',
      'outline-dotted',
      'placeholder',
      'shadow',
      'ring',
      'ring-offset',
      'decoration',
      'c-text-stroke',
    ];

    cssAttrs.forEach((name) => {
      const values = theme('hslColors');

      let order;

      switch (name) {
        case 'text':
          order = 8099;
          break;
        case 'bg':
          order = 1399;
          break;
        case 'border':
        case 'border-t':
        case 'border-r':
        case 'border-b':
        case 'border-l':
          order = 1999;
          break;
        case 'divide':
          order = 599;
          break;
        case 'caret':
          order = 6459;
          break;
        case 'outline':
        case 'outline-solid':
        case 'outline-dotted':
          order = 5899;
          break;
        case 'placeholder':
          order = 6399;
          break;
        case 'shadow':
          order = 6949;
          break;
        case 'ring':
          order = 7399;
          break;
        case 'ring-offset':
          order = 7099;
          break;
        case 'decoration':
          order = 8469;
          break;
        case 'c-text-stroke':
          order = 8559;
          break;
        default:
          order = 20000;
          break;
      }

      for (const [key, value] of Object.entries(values)) {
        const tn = dashToCamel(`${name}-${key}`);

        const steps = [];

        let i = 0;

        do {
          steps.push(i);
          i += 10;
        } while (i <= 100);

        addDynamic(
          `${name}-${key}`,
          ({ Utility, Property, Style }) => {
            const suf = Utility.raw.slice(name.length + 1).split('-');
            const lo = suf[2].split('/');

            const h = value;
            const s = `${suf[1]}%`;
            const l = `${lo[0]}%`;

            const properties = [];

            let varName;

            if (name.startsWith('border')) {
              varName = 'border';
            } else if (name.startsWith('outline')) {
              varName = 'outline';
            } else {
              varName = name;
            }

            const opacity = lo.length === 2 ? (parseFloat(lo[1]) / 100).toString() : '1';
            const color = `hsl(${h} ${s} ${l} / var(--tw-${varName}-opacity))`;
            const colorNoVar = `hsl(${h} ${s} ${l} / ${opacity})`;

            properties.push(Property(`--tw-${varName}-opacity`, opacity));

            switch (name) {
              case 'text':
              case 'placeholder':
                properties.push(Property('color', color));
                break;
              case 'bg':
                properties.push(Property('background-color', color));
                break;
              case 'border':
                properties.push(Property('border-color', color));
                break;
              case 'border-t':
                opacity !== 1 && properties.pop();
                properties.push(Property('border-top-color', opacity === '1' ? color : colorNoVar));
                break;
              case 'border-r':
                opacity !== 1 && properties.pop();
                properties.push(Property('border-right-color', opacity === '1' ? color : colorNoVar));
                break;
              case 'border-b':
                opacity !== 1 && properties.pop();
                properties.push(Property('border-bottom-color', opacity === '1' ? color : colorNoVar));
                break;
              case 'border-l':
                opacity !== 1 && properties.pop();
                properties.push(Property('border-left-color', opacity === '1' ? color : colorNoVar));
                break;
              case 'divide':
                properties.push(Property('border-color', color));
                break;
              case 'caret':
                properties.push(Property('caret-color', color));
                break;
              case 'outline':
              case 'outline-solid':
              case 'outline-dotted':
                properties.push(Property('outline-color', color));
                break;
              case 'shadow':
                properties.pop();
                properties.push(Property('--tw-shadow-color', colorNoVar));
                properties.push(Property('--tw-shadow', 'var(--tw-shadow-colored)'));
                break;
              case 'ring':
              case 'ring-offset':
                properties.push(Property(`--tw-${name}-color`, color));
                break;
              case 'decoration':
                properties.push('-webkit-text-decoration-color', color);
                properties.push('text-decoration-color', color);
                break;
              case 'c-text-stroke':
                properties.push('-webkit-text-stroke-color', color);
                break;
              default:
                break;
            }

            if (name === 'divide') {
              return Style(Utility.class, properties)
                .child('> :not([hidden]) ~ :not([hidden])')
                .updateMeta('utilities', 'divideColor', 400, 0, true);
            }
            if (name === 'placeholder') {
              console.log('config :>> ', config('prefixer'));
              if (!config('prefixer')) {
                return Style(Utility.class, properties);
              }
              return [
                Style(Utility.class, properties).pseudoElement('-webkit-input-placeholder'),
                Style(Utility.class, properties).pseudoElement('-moz-placeholder'),
                Style(Utility.class, properties).pseudoClass('-ms-input-placeholder'),
                Style(Utility.class, properties).pseudoElement('-ms-input-placeholder'),
                Style(Utility.class, properties).pseudoElement('placeholder'),
              ];
            }
            if (name === 'c-text-stroke') {
              // console.log(`${name} :>> `, Utility.class);
              // TODO:: 运行失败，忽略
              // return Style(Utility.class, properties);
              return null;
            }

            return Style(Utility.class, properties);
          },
          {
            layer: 'utilities',
            group: tn,
            completions: steps.map((step) => `${name}-${key}-${step}-{int}`),
            order,
          },
        );
      }
    });
  },
  {
    theme: {
      hslColors: {
        primary: '216',
        secondary: '210',
        success: '152',
        danger: '354',
        warning: '45',
        info: '190',
      },
    },
  },
);

module.exports = hslColors;
